From: Keir Fraser Date: Wed, 17 Feb 2010 12:04:50 +0000 (+0000) Subject: x86/mcheck: do not blindly de-reference dom0 et al X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~12590 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=86fd4176f4c70c830de86503bb5ce72a1f2e76b6;p=xen.git x86/mcheck: do not blindly de-reference dom0 et al Since machine checks and CMCIs can happen before Dom0 even gets constructed, the handlers of these events have to avoid de-referencing respective pointers without checking. Signed-off-by: Jan Beulich --- diff --git a/xen/arch/x86/cpu/mcheck/amd_nonfatal.c b/xen/arch/x86/cpu/mcheck/amd_nonfatal.c index f2fedcd299..68d2e1fee6 100644 --- a/xen/arch/x86/cpu/mcheck/amd_nonfatal.c +++ b/xen/arch/x86/cpu/mcheck/amd_nonfatal.c @@ -84,12 +84,9 @@ static void mce_amd_checkregs(void *info) { mctelem_cookie_t mctc; struct mca_summary bs; - unsigned int event_enabled; mctc = mcheck_mca_logout(MCA_POLLER, mca_allbanks, &bs, NULL); - event_enabled = guest_enabled_event(dom0->vcpu[0], VIRQ_MCA); - if (bs.errcnt && mctc != NULL) { static uint64_t dumpcount = 0; @@ -101,7 +98,7 @@ static void mce_amd_checkregs(void *info) * a simple-minded attempt to avoid spamming the console * for corrected errors in early startup. */ - if (event_enabled) { + if (dom0_vmce_enabled()) { mctelem_commit(mctc); send_guest_global_virq(dom0, VIRQ_MCA); } else if (++dumpcount >= 10) { @@ -136,7 +133,7 @@ static void mce_amd_work_fn(void *data) on_each_cpu(mce_amd_checkregs, data, 1); if (adjust > 0) { - if (!guest_enabled_event(dom0->vcpu[0], VIRQ_MCA) ) { + if (!dom0_vmce_enabled()) { /* Dom0 did not enable VIRQ_MCA, so Xen is reporting. */ printk("MCE: polling routine found correctable error. " " Use mcelog to parse above error output.\n"); diff --git a/xen/arch/x86/cpu/mcheck/mce.c b/xen/arch/x86/cpu/mcheck/mce.c index d5b404aba6..955ed7b78f 100644 --- a/xen/arch/x86/cpu/mcheck/mce.c +++ b/xen/arch/x86/cpu/mcheck/mce.c @@ -414,7 +414,7 @@ void mcheck_cmn_handler(struct cpu_user_regs *regs, long error_code, * as terminal for any context. */ ctx_xen = SEG_PL(regs->cs) == 0; - ctx_dom0 = !ctx_xen && (domid == dom0->domain_id); + ctx_dom0 = !ctx_xen && (domid == 0); ctx_domU = !ctx_xen && !ctx_dom0; xen_state_lost = bs.uc != 0 || (ctx_xen && (bs.pcc || !ripv)) || @@ -463,7 +463,8 @@ void mcheck_cmn_handler(struct cpu_user_regs *regs, long error_code, * XXFM Could add some Solaris dom0 contract kill here? */ if (dom0_state_lost) { - if (guest_has_trap_callback(dom0, 0, TRAP_machine_check)) { + if (dom0 && dom0->max_vcpus && dom0->vcpu[0] && + guest_has_trap_callback(dom0, 0, TRAP_machine_check)) { dom_state = DOM0_TRAP; send_guest_trap(dom0, 0, TRAP_machine_check); /* XXFM case of return with !ripv ??? */ @@ -532,7 +533,7 @@ cmn_handler_done: if (bs.errcnt) { /* Not panicing, so forward telemetry to dom0 now if it * is interested. */ - if (guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) { + if (dom0_vmce_enabled()) { if (mctc != NULL) mctelem_commit(mctc); send_guest_global_virq(dom0, VIRQ_MCA); diff --git a/xen/arch/x86/cpu/mcheck/mce.h b/xen/arch/x86/cpu/mcheck/mce.h index 6a8c8c85b3..cfc26abf4c 100644 --- a/xen/arch/x86/cpu/mcheck/mce.h +++ b/xen/arch/x86/cpu/mcheck/mce.h @@ -55,6 +55,8 @@ void mc_panic(char *s); void x86_mc_get_cpu_info(unsigned, uint32_t *, uint16_t *, uint16_t *, uint32_t *, uint32_t *, uint32_t *, uint32_t *); +#define dom0_vmce_enabled() (dom0 && dom0->max_vcpus && dom0->vcpu[0] \ + && guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) /* Register a handler for machine check exceptions. */ typedef void (*x86_mce_vector_t)(struct cpu_user_regs *, long); diff --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c index be44dcf71c..b8b64921ac 100644 --- a/xen/arch/x86/cpu/mcheck/mce_intel.c +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c @@ -518,7 +518,7 @@ static void mce_softirq(void) } /* Step2: Send Log to DOM0 through vIRQ */ - if (dom0 && guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) { + if (dom0_vmce_enabled()) { mce_printk(MCE_VERBOSE, "MCE: send MCE# to DOM0 through virq\n"); send_guest_global_virq(dom0, VIRQ_MCA); } @@ -864,7 +864,7 @@ static void cmci_discover(void) MCA_CMCI_HANDLER, __get_cpu_var(mce_banks_owned), &bs, NULL); if (bs.errcnt && mctc != NULL) { - if (guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) { + if (dom0_vmce_enabled()) { mctelem_commit(mctc); send_guest_global_virq(dom0, VIRQ_MCA); } else { @@ -979,7 +979,7 @@ fastcall void smp_cmci_interrupt(struct cpu_user_regs *regs) MCA_CMCI_HANDLER, __get_cpu_var(mce_banks_owned), &bs, NULL); if (bs.errcnt && mctc != NULL) { - if (guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) { + if (dom0_vmce_enabled()) { mctelem_commit(mctc); mce_printk(MCE_VERBOSE, "CMCI: send CMCI to DOM0 through virq\n"); send_guest_global_virq(dom0, VIRQ_MCA); diff --git a/xen/arch/x86/cpu/mcheck/non-fatal.c b/xen/arch/x86/cpu/mcheck/non-fatal.c index 5a2f8a4006..124d4aa504 100644 --- a/xen/arch/x86/cpu/mcheck/non-fatal.c +++ b/xen/arch/x86/cpu/mcheck/non-fatal.c @@ -53,7 +53,7 @@ static void mce_checkregs (void *info) * for corrected errors in early startup. */ - if (guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) { + if (dom0_vmce_enabled()) { mctelem_commit(mctc); send_guest_global_virq(dom0, VIRQ_MCA); } else if (++dumpcount >= 10) {